/**
 * @file tsk_task.c
 * @brief tskp库 - 任务调度器模块实现文件
 * @details
 * 本文件实现了tskp任务调参库的任务调度器功能，包括任务注册、注销、启停、优先级调整、任务推送与调度等操作。
 * 支持多优先级、多任务ID，适合嵌入式、实时系统下的高效任务调度与参数管理。
 *
 * 作者：小傲（个人开发）
 * 邮箱：2655640770@qq.com
 * 版权声明：开源公开，欢迎建议与反馈
 * 日期：2025-09-11
 */

#include"tsk_task.h"

#ifdef _TSK_TSKP_

/**
 * @brief        // 初始化任务调度器
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @return       // void
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
void tsk_task_Init(tsk_TaskScheduler *sched){
    int i=0;
    memset(sched,0,sizeof(tsk_TaskScheduler));

    if(!tsk_Bitmap_Init(&sched->id_Bitmap)){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]位图初始化失败,调度器:%p\r\n",sched);
            #else
                printf("[Error] Bitmap initialization failed, Scheduler:%p\r\n",sched);
            #endif
            fflush(stdout);
        #endif
        return;
    }
    for(i=0;i<TSK_MAX_PRIORITY_LEVELS;i++){
        tsk_task_Queue_Init(&(sched->tsk_Queue[i]));
    }
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[调度器]已初始化,支持%d个优先级,%d个任务,调度器:%p\r\n",TSK_MAX_PRIORITY_LEVELS,TSK_MAX_TASKS,sched);
            printf("[调度器]占用内存%d字节\r\n",sizeof(*sched));
        #else
            printf("[Scheduler] Initialized, supports %d priority levels, %d tasks, Scheduler:%p\r\n", TSK_MAX_PRIORITY_LEVELS, TSK_MAX_TASKS, sched);
            printf("[Scheduler] Occupies %d bytes of memory\r\n", sizeof(*sched));
        #endif
        fflush(stdout);
    #endif
    sched->isInit=true;
}

/**
 * @brief        // 停用任务调度器
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @return       // void
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
void tsk_stop_TaskScheduler(tsk_TaskScheduler *sched){
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[停用]调度器已停用,调度器:%p\r\n",sched);
        #else
            printf("[Stop] Scheduler stopped, Scheduler:%p\r\n",sched);
        #endif
        fflush(stdout);
    #endif
    sched->isInit=false;
}

/**
 * @brief        // 启用任务调度器
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @return       // void
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
void tsk_start_TaskScheduler(tsk_TaskScheduler *sched){
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[启用]调度器已启动,支持%d个优先级,%d个任务,调度器:%p\r\n",TSK_MAX_PRIORITY_LEVELS,TSK_MAX_TASKS,sched);
        #else
            printf("[Start] Scheduler started, supports %d priority levels, %d tasks, Scheduler:%p\r\n", TSK_MAX_PRIORITY_LEVELS, TSK_MAX_TASKS, sched);
        #endif
        fflush(stdout);
    #endif
    sched->isInit=true;
}

/**
 * @brief        // 检查ID错误
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // id       : 任务ID
 * @param[in]    // flag     : true表示ID应存在,false表示ID不应存在
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static tsk_task_enum_t tsk_isiderr_task(tsk_TaskScheduler *sched,uint8_t id,bool flag){
    if(!sched->isInit){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]调度器未初始化,调度器:%p\r\n",sched);
            #else
                printf("[Error] Scheduler not initialized, Scheduler:%p\r\n",sched);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_INIT_ERR;
    }
    if(id<0||id>=TSK_MAX_TASKS){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]无效ID,ID:%d\r\n",id);
            #else
                printf("[Error] Invalid ID, ID:%d\r\n",id);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_ID_INVALID;
    }
    if(tsk_Bitmap_test(&sched->id_Bitmap,id)!=flag){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                if(flag){
                    printf("[警告]ID不存在,ID:%d\r\n",id);
                }
                else{
                    printf("[警告]ID存在,ID:%d\r\n",id);
                }
            #else
                if(flag){
                    printf("[Warning] ID does not exist, ID:%d\r\n",id);
                }
                else{
                    printf("[Warning] ID exists, ID:%d\r\n",id);
                }
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_ID_INVALID;
    }
    return TSK_TASK_OK;
}

/**
 * @brief        // 注册任务
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // id       : 任务ID
 * @param[in]    // func     : 任务函数指针
 * @param[in]    // param    : 任务固定参数
 * @param[in]    // priority : 任务优先级
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_register_task(tsk_TaskScheduler *sched,
                                uint8_t id,
                                tsk_Func func,
                                void* param,
                                int priority){
    tsk_task_enum_t task_enum=tsk_isiderr_task(sched,id,false);
    if(task_enum!=TSK_TASK_OK){
        return task_enum;
    }
    if(priority<0||priority>=TSK_MAX_PRIORITY_LEVELS){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]无效优先级,Priority:%d\r\n",priority);
            #else
                printf("[Error] Invalid priority, Priority:%d\r\n",priority);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_PRIORITY_INVALID;
    }
    if(!tsk_Bitmap_set(&sched->id_Bitmap,id)){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]ID无效:ID%d\r\n",id);
            #else
                printf("[Error] Invalid ID: ID%d\r\n",id);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_ID_INVALID;
    }

    tsk_TaskRegistry task;
    task.func=func;
    task.param=param;
    task.priority=priority;
    task.active=true;
    sched->tasks[id]=task;
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[注册]任务ID=%d,优先级=%d,参数=%p\r\n",id,priority,param);
        #else
            printf("[Register] Task ID=%d, Priority=%d, Param=%p\r\n",id,priority,param);
        #endif
        fflush(stdout);
    #endif
    return TSK_TASK_OK;
}

/**
 * @brief        // 注销任务
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // id       : 任务ID
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_close_task(tsk_TaskScheduler *sched,uint8_t id){
    tsk_task_enum_t task_enum=tsk_isiderr_task(sched,id,true);
    if(task_enum!=TSK_TASK_OK){
        return task_enum;
    }
    if(!tsk_Bitmap_clear(&sched->id_Bitmap,id)){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]ID无效:ID%d\r\n",id);
            #else
                printf("[Error] Invalid ID: ID%d\r\n",id);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_ID_INVALID;
    }
    sched->tasks[id].active=false;
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[注销]任务ID=%d\r\n",id);
        #else
            printf("[Unregister] Task ID=%d\r\n",id);
        #endif
        fflush(stdout);
    #endif
    return TSK_TASK_OK;
}

/**
 * @brief        // 停用任务
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // id       : 任务ID
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_stop_task(tsk_TaskScheduler *sched,uint8_t id){
    tsk_task_enum_t task_enum=tsk_isiderr_task(sched,id,true);
    if(task_enum!=TSK_TASK_OK){
        return task_enum;
    }
    sched->tasks[id].active=false;
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[停用]任务ID=%d\r\n",id);
        #else
            printf("[Stop] Task ID=%d\r\n",id);
        #endif
        fflush(stdout);
    #endif
    return TSK_TASK_OK;
}

/**
 * @brief        // 启用任务
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // id       : 任务ID
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_start_task(tsk_TaskScheduler *sched,uint8_t id){
    tsk_task_enum_t task_enum=tsk_isiderr_task(sched,id,true);
    if(task_enum!=TSK_TASK_OK){
        return task_enum;
    }
    sched->tasks[id].active=true;
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[启用]任务ID=%d\r\n",id);
        #else
            printf("[Start] Task ID=%d\r\n",id);
        #endif
        fflush(stdout);
    #endif
    return TSK_TASK_OK;
}

/**
 * @brief        // 设置任务优先级
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // id       : 任务ID
 * @param[in]    // priority : 任务优先级
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_task_setpriority(tsk_TaskScheduler *sched,uint8_t id,int priority){
    tsk_task_enum_t task_enum=tsk_isiderr_task(sched,id,true);
    if(task_enum!=TSK_TASK_OK){
        return task_enum;
    }
    if(priority<0||priority>=TSK_MAX_PRIORITY_LEVELS){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]优先级无效,ID=%d,Priority=%d\r\n",id,priority);
            #else
                printf("[Error] Invalid priority, ID=%d, Priority=%d\r\n",id,priority);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_PRIORITY_INVALID;
    }
    sched->tasks[id].priority=priority;
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[修改]ID=%d,Priority=%d\r\n",id,priority);
        #else
            printf("[Modify] ID=%d, Priority=%d\r\n",id,priority);
        #endif
        fflush(stdout);
    #endif
    return TSK_TASK_OK;
}

/**
 * @brief        // 推送任务到调度器
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // push_parsed : 任务参数结构体
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_Push_task(tsk_TaskScheduler *sched,tsk_Parsed_t push_parsed){
    tsk_task_enum_t task_enum=tsk_isiderr_task(sched,push_parsed.id,true);
    if(task_enum!=TSK_TASK_OK){
        return task_enum;
    }
    tsk_TaskRegistry task=sched->tasks[push_parsed.id];
    if(!task.active){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]任务未激活ID=%d\r\n",push_parsed.id);
            #else
                printf("[Error] Task not active, ID=%d\r\n",push_parsed.id);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_ID_INVALID;
    }
    push_parsed.T_struct=task.param;
    if(Tsk_task_Queue_Push(&(sched->tsk_Queue[task.priority]),push_parsed)!=TSK_TASK_QUEUE_OK){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[警告]优先级任务已满,Parsed=%d\r\n",task.priority);
            #else
                printf("[Warning] Priority queue full, Priority=%d\r\n",task.priority);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_PRIORITY_INVALID;
    }
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[处理]任务已进队ID=%d,Parsed=%d\r\n",push_parsed.id,task.priority);
        #else
            printf("[Process] Task queued, ID=%d, Priority=%d\r\n",push_parsed.id,task.priority);
        #endif
        fflush(stdout);
    #endif
    return TSK_TASK_OK;
}

/**
 * @brief        // 调度一个优先级内的一个任务
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @param[in]    // priority : 任务优先级
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_Run_Priority_TaskScheduler(tsk_TaskScheduler *sched,int priority){
    if(!sched->isInit){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]调度器未初始化,调度器:%p\r\n",sched);
            #else
                printf("[Error] Scheduler not initialized, Scheduler:%p\r\n",sched);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_INIT_ERR;
    }
    if(priority<0||priority>=TSK_MAX_PRIORITY_LEVELS){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]调度,优先级无效,Priority=%d\r\n",priority);
            #else
                printf("[Error] Schedule, invalid priority, Priority=%d\r\n",priority);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_PRIORITY_INVALID;
    }
    tsk_Parsed_t task_Parsed;
    tsk_TaskRegistry task;
    while (!tsk_is_task_Queue_Empty(sched->tsk_Queue[priority])){
        if(!Tsk_task_Queue_Pop(&(sched->tsk_Queue[priority]),&task_Parsed)){
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[错误]调度,优先级队列未空,Priority=%d\r\n",priority);
                #else
                    printf("[Error] Schedule, priority queue not empty, Priority=%d\r\n",priority);
                #endif
                fflush(stdout);
            #endif
            return TSK_TASK_PRIORITY_INVALID;
        }
        tsk_task_enum_t task_enum=tsk_isiderr_task(sched,task_Parsed.id,true);
        //id无效,运行下一个
        if(task_enum!=TSK_TASK_OK){
            continue;
        }
        task=sched->tasks[task_Parsed.id];
        //id停用运行下一个任务
        if(!task.active){
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[处理]调度,ID停用,ID=%d,Priority%d\r\n",task_Parsed.id,priority);
                #else
                    printf("[Process] Schedule, ID stopped, ID=%d, Priority=%d\r\n",task_Parsed.id,priority);
                #endif
                fflush(stdout);
            #endif
            continue;
        }
        if(task.priority!=priority){
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[处理]调度,优先级错误已修改,ID=%d,Priority%d\r\n",task_Parsed.id,priority);
                #else
                    printf("[Process] Schedule, priority error fixed, ID=%d, Priority=%d\r\n",task_Parsed.id,priority);
                #endif
                fflush(stdout);
            #endif
            tsk_Push_task(sched,task_Parsed);//推送到对应优先级队列内
            continue;
        }
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[执行]任务ID=%d\r\n",task_Parsed.id);
            #else
                printf("[Run] Task ID=%d\r\n",task_Parsed.id);
            #endif
            fflush(stdout);
        #endif
        task.func(&task_Parsed);//调度任务
        return TSK_TASK_OK;
    }
    return TSK_TASK_PRIORITY_INVALID;
}

/**
 * @brief        // 调度所有优先级的任务
 * @param[in]    // sched    : 指向tsk_TaskScheduler结构体的指针
 * @return       // tsk_task_enum_t : 任务操作结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
tsk_task_enum_t tsk_Run_TaskScheduler(tsk_TaskScheduler *sched){
    if(!sched->isInit){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]调度器未初始化,调度器:%p\r\n",sched);
            #else
                printf("[Error] Scheduler not initialized, Scheduler:%p\r\n",sched);
            #endif
            fflush(stdout);
        #endif
        return TSK_TASK_INIT_ERR;
    }
    int i=0;
    int count=0;
    for(i=0;i<TSK_MAX_PRIORITY_LEVELS&&count<TSK_ONE_MAX_TASKSCHEDULER;i++){
        while (count<TSK_ONE_MAX_TASKSCHEDULER){
            if(tsk_is_task_Queue_Empty(sched->tsk_Queue[i])){
                break;
            }
            if(tsk_Run_Priority_TaskScheduler(sched,i)==TSK_TASK_OK){
                count++;
            }
            else{
                break;
            }
        }
    }
    return TSK_TASK_OK;
}

#endif // _TSK_TSKP_
